Mar 03

Happy Square Root Day!

Playing a video (of a supported file format) on the iPhone is very easy using the MPMoviePlayerController class. You just create an instance of the class and initialize it with the URL of the video. The controller plays the video in full screen mode and returns back to your application when it’s done.

However, if the URL of the video is recognized by the iPhone as a YouTube URL then the Apple URL Scheme mechanism kicks in and launches the YouTube app. In this scenario control will not return to your app after the video has played. (The behavior is equivalent of calling [UIApplication openURL:] with the video URL.)

One workaround is to use a UIWebView and load it with the video URL. The drawback with this approach is that the user will see the rather ugly YouTube mobile web site and has to find and tap on the link of the video to play it.

YouTube Mobile

 

Another, visually more appealing, option is to create a small UIWebView on your screen and load it with the YouTube embed code. The result is a small button like image that shows the YouTube play button above a screen image from the video. When the user taps the image, the iPhone video player opens in full screen mode as usual, and when the video is done control is returned back to this screen.

YouTube Video Embedded in iPhone App

 

Here’s the code:

- (void)embedYouTube:(NSString*)url frame:(CGRect)frame {
 NSString* embedHTML = @"\
    <html><head>\
 <style type=\"text/css\">\
 body {\
 background-color: transparent;\
 color: white;\
 }\
 </style>\
 </head><body style=\"margin:0\">\
    <embed id=\"yt\" src=\"%@\" type=\"application/x-shockwave-flash\" \
 width=\"%0.0f\" height=\"%0.0f\"></embed>\
    </body></html>";
 NSString* html = [NSString stringWithFormat:embedHTML, url, frame.size.width, frame.size.height];
 if(videoView == nil) {
 	videoView = [[UIWebView alloc] initWithFrame:frame];
 	[self.view addSubview:videoView];
 }
 [videoView loadHTMLString:html baseURL:nil];
}

Tip of the hat to joehewitt.

Update: A complete working Xcode project has been posted here.

written by Nick \\ tags:

94 Responses to “How To Play YouTube Videos Within an Application”

  1. Stefan Shurman Says:

    Hello Nick,

    thanks for this nice tutorial. There’s one question open to me:
    How am I able to receive an event, when the youtube video ends?

    Regards,

    Stefan

  2. iPhoneKicks.com Says:

    How To Play YouTube Videos Within an Application…

    You’ve been kicked (a good thing) – Trackback from iPhoneKicks.com – iPhone SDK links, community driven…

  3. ratbone Says:

    Does the simulator support youtube links?

  4. Nick Says:

    @Stefan: As far as I know there is no event fired when the video ends. In a slightly different situation I examined the view hierarchy to determine if the player window was still visible, which would indicate if the video/audio was playing or not. But this was a terrible hack, so I wouldn’t recommend it.

  5. Nick Says:

    @ratbone: The simulator does not have the QuickTime player plugin, so it does not play YouTube videos. If you were to run the application shown in the screen image above on the simulator, the nice baseball video image would be replaced by the blue Lego block with question marks. (The same symbol you see when you’re browsing a web page with Flash content on your iPhone.)

  6. Stefan Shurman Says:

    @Nick

    Thanks, maybe I’ll find some hack that works for me.

  7. pepersview Says:

    Hello, i have one problem, i tried with the next code, but the simulator didn’t show me the video:

    NSString* htmlString =
    @”\ \ \ body {\ background-color: transparent;\ color: white;\ }\ \ \ \ “;

    [self.window addSubview:webView];
    [webView loadHTMLString:htmlString baseURL:[NSURL URLWithString:@”http://www.google.com”]];

    Thanks!!

  8. Nick Says:

    @pepersview: The simulator does not display videos.

  9. pepersview Says:

    this, means when i will try the same code in the device, it will run?
    And also if the simulator i have:
    “MoviePlayer[234:20b] Warning: MPMoviePlayerController may not support file of type flv” in the log, and in the screen “This movie format is not supported”

    When i will try in the device will run?

    Thanks a lot!!

  10. Nick Says:

    @pepersview: The code in the blog post will play videos on the device, that has been well tested.

    The format of the video has to be one that is supported by the iPhone. Files of the type “flv” are Flash Video files, which do not play the iPhone. Here’s detailed information about which video formats are supported: Technical Note TN2188 – Exporting Movies for iPod, Apple TV and iPhone

  11. E.C. Says:

    I tried the loading a local test.html and worked. Does anyone know how to code the within the test.html do that they point to other local htmls? T
    hanks.

  12. E.C. Says:

    Sorr, the tags did not show . I need to know about how to code the HREFs within the test.html to load other local htmls. thx.

  13. Nick Says:

    @E.C.: There is no web server running on the iPhone so you can’t create HTML links from one file to another.
    The workaround is to override shouldStartLoadWithRequest in your web view, and manually load the new HTML file into the web view.

  14. E.C. Says:

    Thanks Nick. That worked.

  15. iDeveloper Says:

    Thanks, this works great!

  16. Carlo Says:

    Thanks for this great tutorial.
    Do you know if it’s possible to start playing the youtube video automatically as soon as the UIWebView loads the html?
    I cant thnk of a way of doing this.
    Please help

  17. Nick Says:

    @Carlo: You could probably start playing the YouTube video automatically using JavaScript. But since the video plays in full screen mode, why would you want to do that? Instead of having a complicated UIWebView you can just load the video URL directly into a MPMoviePlayerController.

  18. Carlo Says:

    @Nick: Unfortunately i don’t think it’s possible to load youtube videos into MPMoviePlayerController because youtube urls (like http://www.youtube.com/watch?v=jJ9KYriPbU4) dont reference movie files and return html.
    These urls work well in UIWebViews tough.
    Do you have any suggestion about how to start the movie in UIWebView via javascript?
    Does Safari support javascript calls to the flash plugin? and how?

    Regards

  19. jsd Says:

    This is a great tip, and it’s working for me, but only up until the video starts. When I click “done” on the youtube window, it wipes away the entire view that was loaded and shows the one underneath. Any ideas about that?

  20. Nick Says:

    @jsd: The project where I used this technique had the video view on the back side of a view that flipped, so it was not a simple view setup. But I don’t recall having to do anything special to get back to the original view after playing a video. (Search for WDYK on the App Store to see the app.)

  21. Carlo Says:

    Nick, i also tried appending the properties autoplay=1 and autostart=1 to the youtube video url but that doesnt help on the iPhone.
    I really need to play a sequence of yutube videos without the user interacting with the uiwebview.
    Any help will be very appreciated.
    Cheers

  22. Nick Says:

    @Carlo: Load the video URL directly into a MPMoviePlayerController.

  23. Carlo Says:

    Nick,
    i’ve also tryed playing this url
    http://www.youtube.com/swf/l.swf?swf=http%3A//s.ytimg.com/yt/swf/cps-vfl94922.swf&video_id=vUDC15IHOBs&autoplay=1
    (resulting from the youtube redirects)
    into MPMoviePlayerController with similar results:
    “Warning: MPMoviePlayerController may not support file of type swf”

  24. max Says:

    This is really nice. Can someone please post the complete code.

  25. Nick Says:

    @max: Unfortunately I cannot post the complete code as it belongs to a client. If anyone else has incorporated these code snippets feel free to share.

  26. jsd Says:

    I fixed my problem by changing the way my views were laid out and attached to the root. Thanks for the code, it works great!

  27. Gonso Says:

    Hi

    Im trying to use this sample code, but what i get is a tiny youtube icon on the top-left corner of my UIWebView. My view is 320X220 and I have to set the width an height of the embeded object to 700×500 so that it fills 80% of the UIWebView.
    What am I doing wrong?

    The only thing I changed is that the UIWebView is created from the Interface Builder, so I skip the If (videoView == nill) part…

    Thanks
    Gonso

  28. Gonso Says:

    Hi

    Im using this technique to embed videos in my application and once in while the application will crash when I click to see the video.
    I’ve noticed this warning EVERYTIME:
    “/Developer/Platforms/iPhoneOS.platform/DeviceSupport/2.2/Symbols/System/Library/Internet Plug-Ins/YouTubePlugIn.webplugin/YouTubePlugIn” (file not found).

    Is there a way to prevent this warning and crash?

    Thanks

    Gonso

  29. Nick Says:

    @Gonso: I have not seen this warning.

  30. Kevin Says:

    Hi Nick, this works well, but evidently only if you want to only play YouTube movies.

    I am trying to play both YouTube and MPMoviePlayerController videos. I can play them individually just fine. I can play MPMoviePlayerController videos followed by YouTube videos just fine as well.

    However, once I play a YouTube movie and control is returned to my app, the MPMoviePlayerController will not play a movie correctly. You can hear the audio, but get no visuals.

    My guess is that the YouTube player doesn’t release all of its resources when it comes back to the app and they’re the same resources used by the MPMoviePlayerController.

    I even tried releasing the UIWebView associated with the movie after it finished, but that didn’t seem to help.

    Do you have any experience with this or can you offer any suggestions on what might help?

    Thanks,

    Kevin.

  31. Nick Says:

    I have not tried to play movies from YouTube and other sources within the same app, so I have not encountered your problem. I do know that playing multiple movies from YouTube using this technique works fine. And playing multiple movies from another source using MPMoviePlayerController works too. My experience is that the video player is very sensitive to video formats. Maybe it gets confused by different video formats from your two video sources?

  32. Kevin Says:

    Upon further testing, it turns out that the issue is in playing a remote movie file followed by a local movie file.

    It seems that even using straight up MPMoviePlayerController calls, if I play a movie file from a remote server, and then try to play a local movie file, the local one plays audio only and the screen doesn’t change at all (it leaves my last view up).

    Since I can play local movie after local movie, or remote movie after remote movie, I assume that I am properly releasing the MPMoviePlayerController object (I’m doing it the same way as its done in the sample apps and documentation).

    Has anyone else run into this?

    Kevin.

  33. Saurabh Wadhwa Says:

    Is it possible to play a youtube video on click of a button and not a web view.
    Also is it possible to launch youtube player through a youtube URL and getting the control back to the app?

  34. Nick Says:

    @Saurabh: As described in the original post, if you try to open a YouTube URL directly, the YouTube player will be launched and your app loses control. The technique described in the post is one that I’ve found to work. With some clever HTML and JavaScript you could make the web view look like a normal button.

  35. Saurabh Wadhwa Says:

    does anyone how to simulate the click on the youtube player through javascript. What I am trying to do is to click on an image which loads and play the youtube video.I tried to get hold the embedded object through following html+javascript

    function message()
    {
    document.getElementById(“saurabh”).click();
    alert(“This alert box was called with the onload event”);
    }

    <!–

    –>

    This does not seem to work

    Also does anyone know how to autostart or autopplay a youtube video in UIWebView. &autoplay = 1 does not seem to work

  36. Saurabh Wadhwa Says:

    hey Carlo , It seems I have a problem similar to yours . Did u find a javascript to paly the video.I tried with youtube javascript api. But iphone does support swfObject. Help……….

  37. Malay Parekh Says:

    @Gonso: Did you manage to find out about that YouTube plugin warning?

    I have a similar issue on the 3.0 SDK.

  38. Mark Says:

    Does this code still work. I have it in my app and a while back it worked, but it doesn’t work anymore.

    Thanks

  39. Nick Says:

    @Mark: I just tested the code on a 3.0 device, and it’s still working fine.

  40. Avk Says:

    @Kevin,
    You are basically running into a situation where an empty container is shielding your video while you still hear the audio. So you are not releasing the object properly, in case of the MPMoviePlayerController you can register for a MPMoviePlayerPlaybackDidFinishNotification and let the responder to the event stop the object and release it. Don’t know how to release the Youtube properly as it doesn’t have the notification mechanism.

  41. Sikosis Says:

    Yeh I get the same issue as Gonso “tiny youtube icon on the top-left corner of my UIWebView.”

    Any ideas or is that as big as it gets because that’s what size mobile youtube offers ?

  42. Sikosis Says:

    ah I see … I just made those values extremely large and voila.

  43. kungfuslippers Says:

    Hi Nick,

    I’ve embedded some videos in some customised UITableViewCells within a UITableView. (similar to the youtube application) I’ve got an accessory button which is a custom button which responds to accessoryButtonTappedForRowWithIndexPath().

    At the moment if I tap the youtube video icon (which is a UIWebView) within a cell directly the player launches the video and plays it perfectly which is great.

    However if I select elsewhere within the cell I obviously get a call to accessoryButtonTappedForRowWithIndexPath or didSelectRowAtIndexPath.

    My question is…is it possible to somehow direct the cell touch events to the YouTube UIWebView within the cell so that tappping anywhere within the cell launches my video?

  44. Nick Says:

    @kungfuslippers: This might be possible using some clever JavaScript that you call using stringByEvaluatingJavaScriptFromString on the UIWebView. Although I haven’t tried this so I don’t know for sure.

  45. kungfuslippers Says:

    @Nick or anyone else…..

    Any ideas/pointers as to how I’d go about this? I’ve never dabbled in Javascript before?

  46. DenVog Says:

    I ran into a similar issue as kungfuslippers. I created a separate web view to cover the rest of the cell. Made it .02 alpha (essentially invisible, as if alpha is 0 it won’t work), and set the YouTube width in the code snippet to match. From a user perspective, it looks like they’re touching the row. In fact, they’re touching an invisible web view. I know it’s a hack, but it works.

  47. Frank Says:

    GREAT TIPS Can someone upload a piece of code…. ???

  48. kungfuslippers Says:

    @DenVog – thats a cunning plan! I like it. I think it just might work. Well done!

  49. Shades Says:

    @DenVog: Can you paste a small snippet of your code? How to set the alpha?

  50. kungfuslippers Says:

    @DenVog – nearly….Only problem is the user has to ensure they press on the the youtube play icon right in the centre of the cell, otherwise the touch isn’t detected. If you set the alpha to 0.5 so the play icon is just visible and touch outside the play icon you’ll see what I mean……

    @anyone one : How does the youtube app do it??????

  51. DenVog Says:

    @kungfuslippers Per my post, you have to set the YouTube width in the code snippet to match width of the webview. Otherwise it will sit in the middle as you describe. You need it to fill the width. Go look here: http://apiblog.youtube.com/2009/02/youtube-apis-iphone-cool-mobile-apps.html It’s more obvious how to set the width of the video itself, as opposed to the webview.

  52. DenVog Says:

    Is anyone else running into an issue where the thumbnail does not display? Sometimes it works correctly. Other times it just shows the play button with YouTube logo, even though I have network access. Can’t find any rhyme or reason.

  53. kungfuslippers Says:

    @DenVog,

    I set the width element as per the example and it still doesn’t work for me 🙁
    The play icon is still in the middle. Not sure what I’m doing wrong…..

    As per the the thumbnail issue, I get the same as you from time to time.

  54. DenVog Says:

    @Shades I set the alpha in Interface Builder

  55. Shades Says:

    Unfortunately you have to press the small playbutton on the image to make it run. So, if you have a uiwebview over a wide row in a table, you have to press in the middle for it to work (and it might be hard to find the playbutton if it doesn’t show due to the alpha..

  56. kungfuslippers Says:

    @shades – thats exactly my problem too

  57. Shades Says:

    Anyone found out how to send the click to the to the embed or to make the whole youtube click clickable or anything like that?

  58. Abhilash Says:

    Hi All,

    I was able to list the video’s in the tableview cell and each time user has to tap on the thumnail(actually the webview) to open the video. Does any one know’s how to play all the video’s (for eg. i have 10 video’s listed in the cell) in a single tap?

  59. btschumy Says:

    In general this is working well for me. However sometimes the play button in the UIWebView will have the universal “stop” symbol (circle with a slash through it) over it. The playing is disabled. The URLs I’m trying to play are taken from a search using the YouTube API. I’ve not yet figured out why some are playable and some not. Any thoughts?

  60. Nick Says:

    @btschumy: Only YouTube videos that are H.264 encoded will play on the iPhone.

  61. meroon Says:

    For all you trying to directly play the YouTube video without displaying the UIWebView check this article out. http://silentmac.com/?p=453

  62. Nick Says:

    @meroon: This is indeed a cool trick. While it doesn’t use any private API:s, relying on the internal view structure of UIWebView is discouraged by Apple. If you use this technique be sure to have a fallback way to play the video.

  63. meroon Says:

    @Nick: It’s true, if the structure changes yer screwed. But it seems to be the only way. If only the MPMoviePlayerController would support rtsp then I wouldn’t have to do it this way.

  64. Matze Says:

    Hello from Germany.

    I’d like to know if I impinge upon someone’s rights by linking to a youtube video in my application, which I am looking forward to sell in the iTS this year.

    Best regards and thanks in advance for any help, Matze

  65. Nick Says:

    @Matze: I’m not a lawyer, so my answer is based on my experience as a developer and should not be interpreted as legal advice.
    In the WDYK application we display the name of the author of the YouTube clip next to the play button inside the app. The idea is to make it very clear that the video is not ours, but belongs to someone else and we’re just linking to it.
    You can download the WDYK app free from the App Store, or just look at the screen images in iTunes and you’ll see the author label.

Leave a Reply